<?php

namespace App\Services;

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use common\utils\RedisKeys;
use common\utils\SysCode;
use App\Models\Setting;
use App\Models\SettingLog;

class SettingService
{
    // JWT Token
    const JWT_TOKEN = 'JWT_TOKEN';
    // APP 加解密秘钥
    const APP_KEY = 'APP_KEY';
    // 签名秘钥
    const SIGN_KEY = 'SIGN_KEY';
    // 用户注册开关
    const USER_REGISTER_SWITCH = 'USER_REGISTER_SWITCH';
    // 用户STEAM开关
    const USER_REGISTER_STEAM = 'USER_REGISTER_STEAM';
    // 基础设置配置
    const BASIC_SETTING = 'BASIC_SETTING';
    // 出款稽核核算比例配置
    const VALID_BET_PERCENT_SETTING = 'VALID_BET_PERCENT_SETTING';
    //客服配置
    const SET_3TH_SERVICE = 'SET_3TH_SERVICE';
    //代理注册配置
    const SET_REGISTER_AGENT = 'SET_REGISTER_AGENT';
    //代理注册条例
    const SET_REGISTER_AGENT_ORDINANCE = 'SET_REGISTER_AGENT_ORDINANCE';
    //会员注册PC配置
    const SET_REGISTER_USER_PC = 'SET_REGISTER_USER_PC';
    //会员注册H5配置
    const SET_REGISTER_USER_H5 = 'SET_REGISTER_USER_H5';
    //财务设置->出入款限制
    const RECHARGE_WITHDRAW_LIMIT = 'RECHARGE_WITHDRAW_LIMIT';

    // 公共配置，不分库
    public static $globalSetting = [
        self::JWT_TOKEN,
        self::APP_KEY,
        self::SIGN_KEY,
    ];

    public static $items = [
        self::JWT_TOKEN => 'string',
        self::APP_KEY => 'string',
        self::SIGN_KEY => 'string',
        self::USER_REGISTER_SWITCH => 'bool',
        self::USER_REGISTER_STEAM => 'bool',
        self::BASIC_SETTING => 'array',
        self::VALID_BET_PERCENT_SETTING => 'array',
        self::SET_3TH_SERVICE => 'array',
        self::SET_REGISTER_AGENT => 'array',
        self::SET_REGISTER_AGENT_ORDINANCE => 'string',
        self::SET_REGISTER_USER_PC => 'array',
        self::SET_REGISTER_USER_H5 => 'array',
        self::RECHARGE_WITHDRAW_LIMIT => 'array',
    ];

    private static function getTypeFunc($key, $isGet = true)
    {
        if (!isset(self::$items[$key])) {
            Log::error("GetTypeFunc Error: Unknown key!", [$key]);
            return null;
        }
        $f = $isGet ? 'get' : 'set';
        switch (self::$items[$key]) {
            case 'bool':
            case 'array':
                $f .= ucfirst(self::$items[$key]);
                break;
            case 'string':
                break;
            default:
                Log::error("GetTypeFunc Error: Unknown type ", [$key, self::$items[$key]]);
                return null;
        }
        return $f;
    }

    public static function getItem($key)
    {
        $f = self::getTypeFunc($key);
        return $f ? self::$f($key) : null;
    }

    public static function setItem($key, $value)
    {
        $f = self::getTypeFunc($key, false);
        return $f ? self::$f($key, $value) : false;
    }

    public static function getArray($key)
    {
        $arr = self::get($key);
        if (!$arr) {
            return [];
        }
        return json_decode($arr, true);
    }

    public static function setArray($key, $value)
    {
        return self::set($key, json_encode($value));
    }

    public static function getBool($key)
    {
        return self::get($key) == 1;
    }

    public static function setBool($key, $value)
    {
        return self::set($key, $value ? 1 : 0);
    }

    public static function get($key, $cache = true)
    {
        $redis = Redis::connection();
        if ($cache) {
            $value = $redis->get(RedisKeys::SETTING_KEY . $key);
            if ($value != null) {
                return $value;
            }
        }
        $query = Setting::where(['key' => $key]);
        // 公共配置使用全局hall_id
        if (in_array($key, self::$globalSetting)) {
            $query->where(['hall_id' => 0]);
        }
        $setting = $query->first();
        if ($setting) {
            $redis->set(RedisKeys::SETTING_KEY . $key, $setting->value);
            return $setting->value;
        }
        return null;
    }

    public static function set($key, $value)
    {
        DB::beginTransaction();
        try {
            $old = self::get($key, false);
            if ($old === null) {
                $old = '';
                $setting = new Setting();
                $setting->key = $key;
                $setting->value = $value;
                $setting->save();
            } else {
                Setting::where(['key' => $key])->update(['value' => 1]);
            }

            $log = new SettingLog();
            $log->key = $key;
            $log->new = $value;
            $log->old = $old;
            $user = Auth::user();
            if ($user) {
                $log->updater_id = $user->id;
                $log->updater_name = $user->username;
            }
            $log->save();
            DB::commit();

            $redis = Redis::connection();
            $redis->set(RedisKeys::SETTING_KEY . $key, $value);
            return true;
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error("Setting Error: " . $e->getMessage(), ['key' => $key, 'value' => $value]);
            return false;
        }
    }
}
